#include "client.h"

int main(int argc, char* argv[])
{
    ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    ERROR_CHECK(sockfd,-1,"socket");
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    int ret = connect(sockfd,(struct sockaddr *)&addr,sizeof(addr));
    ERROR_CHECK(ret,-1,"connect");
    printf("The client is ready!\n");

    char CMD[128];
    char buffer[4096];
    train_t sendTrain;
    train_t recvTrain;
    while(1){
        fflush(stdin);
        char *part1 = (char*)malloc(sizeof(char));
        char *part2 = (char*)malloc(sizeof(char));
        bzero(sendTrain.buf,sizeof(sendTrain.buf));
        bzero(recvTrain.buf,sizeof(recvTrain.buf));
        bzero(CMD,sizeof(CMD));
        bzero(buffer,sizeof(buffer));
        read(STDIN_FILENO,CMD,sizeof(CMD));
        fflush(stdin);
        strtok(CMD,"\n");
        if(strncmp(CMD,"cd",2) == 0){
            printf("CMD : cd\n");
            fflush(stdout);
            part1 = strtok_r(CMD," ",&part2);
            sendTrain.status = OD_CD;
            sendTrain.length = strlen(part2);
            strcpy(sendTrain.buf,part2);
            send(sockfd,&sendTrain.status,sizeof(int),MSG_WAITALL);
            send(sockfd,&sendTrain.length,sizeof(int),MSG_WAITALL);
            send(sockfd,sendTrain.buf,sendTrain.length,MSG_WAITALL);
            recvn(sockfd,&recvTrain.length,sizeof(int));
            recvn(sockfd,recvTrain.buf,recvTrain.length);
            strcpy(buffer,recvTrain.buf);
            printf("%s\n",buffer);
            fflush(stdout);
            free(part1);
            free(part2);
        }else if(strncmp(CMD,"ls",2) == 0){
            printf("CMD : ls\n");
            fflush(stdout);
            sendTrain.status = OD_LS;
            send(sockfd,&sendTrain.status,sizeof(int),MSG_WAITALL);
            recvn(sockfd,&recvTrain.length,sizeof(int));
            recvn(sockfd,recvTrain.buf,recvTrain.length);
            strcpy(buffer,recvTrain.buf);
            printf("%s\n",buffer);
            fflush(stdout);
            free(part1);
            free(part2);
        }else if(strncmp(CMD,"puts",4) == 0){
            printf("CMD : puts\n");
            fflush(stdout);
            part1 = strtok_r(CMD," ",&part2);
            sendTrain.status = OD_PTS;
            sendTrain.length = strlen(part2);
            strcpy(sendTrain.buf,part2);
            send(sockfd,&sendTrain.status,sizeof(int),MSG_WAITALL);
            send(sockfd,&sendTrain.length,sizeof(int),MSG_WAITALL);
            send(sockfd,sendTrain.buf,sendTrain.length,MSG_WAITALL);
            int fd = open(part2,O_RDWR);
            ERROR_CHECK(fd,-1,"open");
            struct stat statbuf;
            fstat(fd,&statbuf);
            sendTrain.length = (int)(statbuf.st_size);
            bzero(sendTrain.buf,sizeof(sendTrain.buf));
            memcpy(sendTrain.buf,&statbuf.st_size,sendTrain.length);
            send(sockfd,&sendTrain.length,sizeof(int),MSG_WAITALL);
            sendfile(sockfd,fd,NULL,statbuf.st_size);
            free(part1);
            free(part2);
        }else if(strncmp(CMD,"gets",4) == 0){
            printf("CMD : gets\n");
            fflush(stdout);
            part1 = strtok_r(CMD," ",&part2);
            sendTrain.status = OD_GTC;
            sendTrain.length = strlen(part2);
            strcpy(sendTrain.buf,part2);
            send(sockfd,&sendTrain.status,sizeof(int),MSG_WAITALL);
            send(sockfd,&sendTrain.length,sizeof(int),MSG_WAITALL);
            send(sockfd,sendTrain.buf,sendTrain.length,MSG_WAITALL);
            recvfile(sockfd,part2);
            free(part1);
            free(part2);
        }else if(strncmp(CMD,"rm",2) == 0){
            printf("CMD : rm\n");
            fflush(stdout);
            part1 = strtok_r(CMD," ",&part2);
            sendTrain.status = OD_RM;
            sendTrain.length = strlen(part2);
            strcpy(sendTrain.buf,part2);
            send(sockfd,&sendTrain.status,sizeof(int),MSG_WAITALL);
            send(sockfd,&sendTrain.length,sizeof(int),MSG_WAITALL);
            send(sockfd,sendTrain.buf,sendTrain.length,MSG_WAITALL);
            free(part1);
            free(part2);
        }else if(strncmp(CMD,"pwd",3) == 0){
            printf("CMD : pwd\n");
            fflush(stdout);
            part1 = strtok_r(CMD," ",&part2);
            sendTrain.status = OD_PWD;
            send(sockfd,&sendTrain.status,sizeof(int),MSG_WAITALL);
            recvn(sockfd,&recvTrain.length,sizeof(int));
            recvn(sockfd,recvTrain.buf,recvTrain.length);
            strcpy(buffer,recvTrain.buf);
            printf("%s\n",buffer);
            fflush(stdout);
            free(part1);
            free(part2);
        }else if(strncmp(CMD,"mkdir",5) == 0){
            printf("CMD : mkdir\n");
            fflush(stdout);
            part1 = strtok_r(CMD," ",&part2);
            sendTrain.status = OD_MD;
            sendTrain.length = strlen(part2);
            strcpy(sendTrain.buf,part2);
            send(sockfd,&sendTrain.status,sizeof(int),MSG_WAITALL);
            send(sockfd,&sendTrain.length,sizeof(int),MSG_WAITALL);
            send(sockfd,sendTrain.buf,sendTrain.length,MSG_WAITALL);
            free(part1);
            free(part2);
        }else if(strncmp(CMD,"rmdir",5) == 0){
            printf("CMD : rmdir\n");
            fflush(stdout);
            part1 = strtok_r(CMD," ",&part2);
            sendTrain.status = OD_RD;
            sendTrain.length = strlen(part2);
            strcpy(sendTrain.buf,part2);
            send(sockfd,&sendTrain.status,sizeof(int),MSG_WAITALL);
            send(sockfd,&sendTrain.length,sizeof(int),MSG_WAITALL);
            send(sockfd,sendTrain.buf,sendTrain.length,MSG_WAITALL);
            free(part1);
            free(part2);
        }else if(strncmp(CMD,"exit",4) == 0){
            printf("CMD : exit\n");
            fflush(stdout);
            send(sockfd,sendTrain.buf,0,0);
            free(part1);
            free(part2);
            close(sockfd);
            return 0;
        }
    }
    return 0;
}

